#ifndef GRID_H
#define GRID_H

#define MAX_NEIGHBORS 10

#include "hash.h"
#include "stdint.h"
#include "edges.h"

using namespace glm;

typedef struct gb {
    /* 8 bits of vertex information
     *   76543210
     *   00010001
     *
     *   00010001 means vertices 0 and 4 are in the volume
     */
    /*uint8_t verts;
    Vertex points[12];*/
    uint8_t verts;

    gb() {
        verts = 0;
        /*for (int i = 0; i < sizeof(points); i++)
            points[i].active = false;*/

    }
} GBox;

typedef struct v {
    vec3 pos, next_pos;
    struct v **neighbors;
    bool active;
   // vec3 min, max;
    int neighbor_count;
    

    v() {
        active = false;
        neighbors = (struct v**) calloc(sizeof(struct v*), MAX_NEIGHBORS);
        neighbor_count = 0;
    }

    void addNeighbor(struct v *n);

    ~v() {
        free(neighbors);
    }
} Vertex;

typedef struct g {
    int res;
    vec3 min, max, delta;
   // vec3 *verts;
    bool *grid_points;
    GBox *boxes;
    Vertex *edge_points;
    HashTable *hash;

    g(HashTable *h, vec3 mi, vec3 ma, int r) {
        hash = h;
        min = mi + vec3(-0.34, -0.34, -0.34);
        max = ma + vec3(0.34, 0.34, 0.34);
        res = r;
        delta = (max - min) / ((float) res);
        boxes = (GBox *) calloc(sizeof(GBox), res * res * res);
        grid_points = (bool *) calloc(sizeof(bool), 
         (res + 1) * (res + 1) * (res + 1));
        /*edge_points = (Vertex *) calloc(sizeof(Vertex), 
         res * (res + 1) * 3 * (res + 1));*/
        printf("Making edge points\n");
        edge_points = new Vertex[res*(res+1) * 3 * (res + 1)];
        if (!edge_points)
            perror("calloc");
        assert(edge_points != NULL);
        //verts = (vec3 *) calloc(sizeof(vec3), 
        // (res + 1) * (res + 1) * res * 3);

        /*for (int i = 0 ; i < (res + 1) * (res + 1) * res * 3; i++) {
            verts[i] = vec3(0.f);
        }*/
    }

    /* sets the values of the vertices in every GBox */
    void generateVertices();
    void smoothVertices(int iter);
    int getIndex(int i, int tx, int ty);
    vec3 getTri(int val, vec3 pos, vec3 delta);

    ~g() {
        //free(verts);
    }
} Grid;

#endif
